package net.butfly.bus.server.invoker.impl;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.butfly.bus.TX;
import net.butfly.bus.context.Constants;
import net.butfly.bus.exception.BusRuntimeException;
import net.butfly.bus.server.ServerConfig;
import net.butfly.bus.server.invoker.BeanWrapper;
import net.butfly.bus.server.invoker.Invoker;
import net.butfly.bus.server.invoker.InvokerProvider;
import net.butfly.bus.util.LogUtils;


public abstract class ProviderBase implements InvokerProvider {
	private static LogUtils logger = LogUtils.getLog();

	private Map<String, BeanWrapper> reg;

	private boolean initDone;

	public void init() {
		if (!initDone) {
			reg = new HashMap<String, BeanWrapper>();
			List<Object> beans = getBeanList();
			Class<?> clz;
			try {
				for (Object bean : beans) {
					clz = bean.getClass();
					v(clz, bean);

					Class<?>[] interfaces = clz.getInterfaces();
					if (interfaces != null) {
						for (Class<?> tClz : interfaces) {
							v(tClz, bean);
						}
					}
				}
			} catch (Exception _ex) {
				throw new BusRuntimeException(Constants.BusinessError.CONFIG_ERROR, _ex);
			}
			initDone = true;
		}
	}

	protected void v(Class<?> clz, Object bean) throws SecurityException, NoSuchMethodException {
		Method[] mAry;
		String serviceKey;
		BeanWrapper bw;
		TX tx;
		String configTxAnnotation = ServerConfig.getTxAnnotation();
		while (clz != null && !clz.equals(Object.class)) {
			mAry = clz.getDeclaredMethods();
			if (mAry != null && mAry.length > 0) {
				for (Method m : mAry) {
					serviceKey = null;
					tx = m.getAnnotation(TX.class);
					if (tx == null) {
						Annotation[] atAry = m.getAnnotations();
						if (atAry.length > 0) {
							for (Annotation at : atAry) {
								if (configTxAnnotation != null && at.annotationType().getName().equals(configTxAnnotation)) {// 兼容之前的ebase中的TX
									String ts = at.toString(), code = null, version = null;
									ts = ts.substring(ts.indexOf("(") + 1, ts.length() - 1);
									String[] tAry = ts.split(",");
									for (String t : tAry) {
										if (t.indexOf("version=") != -1) {
											version = t.substring(t.indexOf("=") + 1);
										} else if (t.indexOf("value=") != -1) {
											code = t.substring(t.indexOf("=") + 1);
										}
									}
									if (code != null && version != null) {
										serviceKey = ServerConfig.getServiceKey(code, version);
									}
									break;
								}
							}
						}
					} else {
						serviceKey = ServerConfig.getServiceKey(tx.value(), tx.version());
					}
					if (serviceKey != null) {
						if (reg.get(serviceKey) == null) {
							logger.info("扫描到交易:" + serviceKey + ".");
							bw = new BeanWrapper(bean, m);
							reg.put(serviceKey, bw);
						}
					}
				}
			}
			clz = clz.getSuperclass();
		}
	}

	protected abstract List<Object> getBeanList();

	public Invoker createInvoker() {
		return new LocalInvoker(reg);
	}
}
